mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-03 12:35:58 +00:00
Bug 1185800 - Add DecoderFlags and SurfaceFlags enum classes and use them instead of imgIContainer flags in all decoder-related code. r=tn
This commit is contained in:
parent
34ac6552ef
commit
f89ca1d90f
@ -47,35 +47,37 @@ public:
|
||||
static void Dispatch(RasterImage* aImage,
|
||||
Progress aProgress,
|
||||
const nsIntRect& aInvalidRect,
|
||||
uint32_t aFlags)
|
||||
SurfaceFlags aSurfaceFlags)
|
||||
{
|
||||
MOZ_ASSERT(aImage);
|
||||
|
||||
nsCOMPtr<nsIRunnable> worker =
|
||||
new NotifyProgressWorker(aImage, aProgress, aInvalidRect, aFlags);
|
||||
new NotifyProgressWorker(aImage, aProgress, aInvalidRect, aSurfaceFlags);
|
||||
NS_DispatchToMainThread(worker);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mImage->NotifyProgress(mProgress, mInvalidRect, mFlags);
|
||||
mImage->NotifyProgress(mProgress, mInvalidRect, mSurfaceFlags);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
NotifyProgressWorker(RasterImage* aImage, Progress aProgress,
|
||||
const nsIntRect& aInvalidRect, uint32_t aFlags)
|
||||
NotifyProgressWorker(RasterImage* aImage,
|
||||
Progress aProgress,
|
||||
const nsIntRect& aInvalidRect,
|
||||
SurfaceFlags aSurfaceFlags)
|
||||
: mImage(aImage)
|
||||
, mProgress(aProgress)
|
||||
, mInvalidRect(aInvalidRect)
|
||||
, mFlags(aFlags)
|
||||
, mSurfaceFlags(aSurfaceFlags)
|
||||
{ }
|
||||
|
||||
nsRefPtr<RasterImage> mImage;
|
||||
const Progress mProgress;
|
||||
const nsIntRect mInvalidRect;
|
||||
const uint32_t mFlags;
|
||||
const SurfaceFlags mSurfaceFlags;
|
||||
};
|
||||
|
||||
class NotifyDecodeCompleteWorker : public nsRunnable
|
||||
@ -470,17 +472,17 @@ DecodePool::NotifyProgress(Decoder* aDecoder)
|
||||
MOZ_ASSERT(aDecoder);
|
||||
|
||||
if (!NS_IsMainThread() ||
|
||||
(aDecoder->GetFlags() & imgIContainer::FLAG_ASYNC_NOTIFY)) {
|
||||
(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) {
|
||||
NotifyProgressWorker::Dispatch(aDecoder->GetImage(),
|
||||
aDecoder->TakeProgress(),
|
||||
aDecoder->TakeInvalidRect(),
|
||||
aDecoder->GetDecodeFlags());
|
||||
aDecoder->GetSurfaceFlags());
|
||||
return;
|
||||
}
|
||||
|
||||
aDecoder->GetImage()->NotifyProgress(aDecoder->TakeProgress(),
|
||||
aDecoder->TakeInvalidRect(),
|
||||
aDecoder->GetDecodeFlags());
|
||||
aDecoder->GetSurfaceFlags());
|
||||
}
|
||||
|
||||
void
|
||||
@ -489,7 +491,7 @@ DecodePool::NotifyDecodeComplete(Decoder* aDecoder)
|
||||
MOZ_ASSERT(aDecoder);
|
||||
|
||||
if (!NS_IsMainThread() ||
|
||||
(aDecoder->GetFlags() & imgIContainer::FLAG_ASYNC_NOTIFY)) {
|
||||
(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) {
|
||||
NotifyDecodeCompleteWorker::Dispatch(aDecoder);
|
||||
return;
|
||||
}
|
||||
|
@ -31,13 +31,11 @@ Decoder::Decoder(RasterImage* aImage)
|
||||
, mFrameCount(0)
|
||||
, mFailCode(NS_OK)
|
||||
, mChunkCount(0)
|
||||
, mFlags(0)
|
||||
, mDecoderFlags(DefaultDecoderFlags())
|
||||
, mSurfaceFlags(DefaultSurfaceFlags())
|
||||
, mBytesDecoded(0)
|
||||
, mInitialized(false)
|
||||
, mMetadataDecode(false)
|
||||
, mSendPartialInvalidations(false)
|
||||
, mImageIsTransient(false)
|
||||
, mFirstFrameDecode(false)
|
||||
, mInFrame(false)
|
||||
, mDataDone(false)
|
||||
, mDecodeDone(false)
|
||||
@ -235,7 +233,9 @@ Decoder::CompleteDecode()
|
||||
// If this image wasn't animated and isn't a transient image, mark its frame
|
||||
// as optimizable. We don't support optimizing animated images and
|
||||
// optimizing transient images isn't worth it.
|
||||
if (!HasAnimation() && !mImageIsTransient && mCurrentFrame) {
|
||||
if (!HasAnimation() &&
|
||||
!(mDecoderFlags & DecoderFlags::IMAGE_IS_TRANSIENT) &&
|
||||
mCurrentFrame) {
|
||||
mCurrentFrame->SetOptimizable();
|
||||
}
|
||||
}
|
||||
@ -249,8 +249,8 @@ Decoder::AllocateFrame(uint32_t aFrameNum,
|
||||
uint8_t aPaletteDepth)
|
||||
{
|
||||
mCurrentFrame = AllocateFrameInternal(aFrameNum, aTargetSize, aFrameRect,
|
||||
GetDecodeFlags(), aFormat,
|
||||
aPaletteDepth, mCurrentFrame.get());
|
||||
aFormat, aPaletteDepth,
|
||||
mCurrentFrame.get());
|
||||
|
||||
if (mCurrentFrame) {
|
||||
// Gather the raw pointers the decoders will use.
|
||||
@ -276,7 +276,6 @@ RawAccessFrameRef
|
||||
Decoder::AllocateFrameInternal(uint32_t aFrameNum,
|
||||
const nsIntSize& aTargetSize,
|
||||
const nsIntRect& aFrameRect,
|
||||
uint32_t aDecodeFlags,
|
||||
SurfaceFormat aFormat,
|
||||
uint8_t aPaletteDepth,
|
||||
imgFrame* aPreviousFrame)
|
||||
@ -304,8 +303,7 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
|
||||
}
|
||||
|
||||
nsRefPtr<imgFrame> frame = new imgFrame();
|
||||
bool nonPremult =
|
||||
aDecodeFlags & imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
|
||||
bool nonPremult = bool(mSurfaceFlags & SurfaceFlags::NO_PREMULTIPLY_ALPHA);
|
||||
if (NS_FAILED(frame->InitForDecoder(aTargetSize, aFrameRect, aFormat,
|
||||
aPaletteDepth, nonPremult))) {
|
||||
NS_WARNING("imgFrame::Init should succeed");
|
||||
@ -322,7 +320,7 @@ Decoder::AllocateFrameInternal(uint32_t aFrameNum,
|
||||
InsertOutcome outcome =
|
||||
SurfaceCache::Insert(frame, ImageKey(mImage.get()),
|
||||
RasterSurfaceKey(aTargetSize,
|
||||
aDecodeFlags,
|
||||
mSurfaceFlags,
|
||||
aFrameNum),
|
||||
Lifetime::Persistent);
|
||||
if (outcome == InsertOutcome::FAILURE) {
|
||||
@ -437,7 +435,7 @@ Decoder::PostFrameStop(Opacity aFrameOpacity /* = Opacity::TRANSPARENT */,
|
||||
|
||||
// If we're not sending partial invalidations, then we send an invalidation
|
||||
// here when the first frame is complete.
|
||||
if (!mSendPartialInvalidations && !HasAnimation()) {
|
||||
if (!ShouldSendPartialInvalidations() && !HasAnimation()) {
|
||||
mInvalidRect.UnionRect(mInvalidRect,
|
||||
gfx::IntRect(gfx::IntPoint(0, 0), GetSize()));
|
||||
}
|
||||
@ -454,7 +452,7 @@ Decoder::PostInvalidation(const nsIntRect& aRect,
|
||||
|
||||
// Record this invalidation, unless we're not sending partial invalidations
|
||||
// or we're past the first frame.
|
||||
if (mSendPartialInvalidations && !HasAnimation()) {
|
||||
if (ShouldSendPartialInvalidations() && !HasAnimation()) {
|
||||
mInvalidRect.UnionRect(mInvalidRect, aRect);
|
||||
mCurrentFrame->ImageUpdated(aRectAtTargetSize.valueOr(aRect));
|
||||
}
|
||||
|
@ -10,9 +10,11 @@
|
||||
#include "RasterImage.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "DecodePool.h"
|
||||
#include "DecoderFlags.h"
|
||||
#include "ImageMetadata.h"
|
||||
#include "Orientation.h"
|
||||
#include "SourceBuffer.h"
|
||||
#include "SurfaceFlags.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -137,24 +139,6 @@ public:
|
||||
*/
|
||||
virtual void SetResolution(const gfx::IntSize& aResolution) { }
|
||||
|
||||
/**
|
||||
* Set whether should send partial invalidations.
|
||||
*
|
||||
* If @aSend is true, we'll send partial invalidations when decoding the first
|
||||
* frame of the image, so image notifications observers will be able to
|
||||
* gradually draw in the image as it downloads.
|
||||
*
|
||||
* If @aSend is false (the default), we'll only send an invalidation when we
|
||||
* complete the first frame.
|
||||
*
|
||||
* This must be called before Init() is called.
|
||||
*/
|
||||
void SetSendPartialInvalidations(bool aSend)
|
||||
{
|
||||
MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
|
||||
mSendPartialInvalidations = aSend;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an iterator to the SourceBuffer which will feed data to this decoder.
|
||||
*
|
||||
@ -171,27 +155,21 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether this decoder is associated with a transient image. The decoder
|
||||
* may choose to avoid certain optimizations that don't pay off for
|
||||
* short-lived images in this case.
|
||||
* Should this decoder send partial invalidations?
|
||||
*/
|
||||
void SetImageIsTransient(bool aIsTransient)
|
||||
bool ShouldSendPartialInvalidations() const
|
||||
{
|
||||
MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
|
||||
mImageIsTransient = aIsTransient;
|
||||
return !(mDecoderFlags & DecoderFlags::IS_REDECODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether we should stop decoding after the first frame.
|
||||
* Should we stop decoding after the first frame?
|
||||
*/
|
||||
void SetIsFirstFrameDecode()
|
||||
bool IsFirstFrameDecode() const
|
||||
{
|
||||
MOZ_ASSERT(!mInitialized, "Shouldn't be initialized yet");
|
||||
mFirstFrameDecode = true;
|
||||
return bool(mDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY);
|
||||
}
|
||||
|
||||
bool IsFirstFrameDecode() const { return mFirstFrameDecode; }
|
||||
|
||||
size_t BytesDecoded() const { return mBytesDecoded; }
|
||||
|
||||
// The amount of time we've spent inside Write() so far for this decoder.
|
||||
@ -255,9 +233,26 @@ public:
|
||||
SEQUENTIAL // decode to final image immediately
|
||||
};
|
||||
|
||||
void SetFlags(uint32_t aFlags) { mFlags = aFlags; }
|
||||
uint32_t GetFlags() const { return mFlags; }
|
||||
uint32_t GetDecodeFlags() const { return DecodeFlags(mFlags); }
|
||||
/**
|
||||
* Get or set the DecoderFlags that influence the behavior of this decoder.
|
||||
*/
|
||||
void SetDecoderFlags(DecoderFlags aDecoderFlags)
|
||||
{
|
||||
MOZ_ASSERT(!mInitialized);
|
||||
mDecoderFlags = aDecoderFlags;
|
||||
}
|
||||
DecoderFlags GetDecoderFlags() const { return mDecoderFlags; }
|
||||
|
||||
/**
|
||||
* Get or set the SurfaceFlags that select the kind of output this decoder
|
||||
* will produce.
|
||||
*/
|
||||
void SetSurfaceFlags(SurfaceFlags aSurfaceFlags)
|
||||
{
|
||||
MOZ_ASSERT(!mInitialized);
|
||||
mSurfaceFlags = aSurfaceFlags;
|
||||
}
|
||||
SurfaceFlags GetSurfaceFlags() const { return mSurfaceFlags; }
|
||||
|
||||
bool HasSize() const { return mImageMetadata.HasSize(); }
|
||||
|
||||
@ -405,7 +400,6 @@ protected:
|
||||
RawAccessFrameRef AllocateFrameInternal(uint32_t aFrameNum,
|
||||
const nsIntSize& aTargetSize,
|
||||
const nsIntRect& aFrameRect,
|
||||
uint32_t aDecodeFlags,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
uint8_t aPaletteDepth,
|
||||
imgFrame* aPreviousFrame);
|
||||
@ -432,14 +426,12 @@ private:
|
||||
TimeDuration mDecodeTime;
|
||||
uint32_t mChunkCount;
|
||||
|
||||
uint32_t mFlags;
|
||||
DecoderFlags mDecoderFlags;
|
||||
SurfaceFlags mSurfaceFlags;
|
||||
size_t mBytesDecoded;
|
||||
|
||||
bool mInitialized : 1;
|
||||
bool mMetadataDecode : 1;
|
||||
bool mSendPartialInvalidations : 1;
|
||||
bool mImageIsTransient : 1;
|
||||
bool mFirstFrameDecode : 1;
|
||||
bool mInFrame : 1;
|
||||
bool mDataDone : 1;
|
||||
bool mDecodeDone : 1;
|
||||
|
@ -109,28 +109,26 @@ DecoderFactory::CreateDecoder(DecoderType aType,
|
||||
RasterImage* aImage,
|
||||
SourceBuffer* aSourceBuffer,
|
||||
const Maybe<IntSize>& aTargetSize,
|
||||
uint32_t aFlags,
|
||||
DecoderFlags aDecoderFlags,
|
||||
SurfaceFlags aSurfaceFlags,
|
||||
int aSampleSize,
|
||||
const IntSize& aResolution,
|
||||
bool aIsRedecode,
|
||||
bool aImageIsTransient)
|
||||
const IntSize& aResolution)
|
||||
{
|
||||
if (aType == DecoderType::UNKNOWN) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<Decoder> decoder = GetDecoder(aType, aImage, aIsRedecode);
|
||||
nsRefPtr<Decoder> decoder =
|
||||
GetDecoder(aType, aImage, bool(aDecoderFlags & DecoderFlags::IS_REDECODE));
|
||||
MOZ_ASSERT(decoder, "Should have a decoder now");
|
||||
|
||||
// Initialize the decoder.
|
||||
decoder->SetMetadataDecode(false);
|
||||
decoder->SetIterator(aSourceBuffer->Iterator());
|
||||
decoder->SetFlags(aFlags);
|
||||
decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::FIRST_FRAME_ONLY);
|
||||
decoder->SetSurfaceFlags(aSurfaceFlags);
|
||||
decoder->SetSampleSize(aSampleSize);
|
||||
decoder->SetResolution(aResolution);
|
||||
decoder->SetSendPartialInvalidations(!aIsRedecode);
|
||||
decoder->SetImageIsTransient(aImageIsTransient);
|
||||
decoder->SetIsFirstFrameDecode();
|
||||
|
||||
// Set a target size for downscale-during-decode if applicable.
|
||||
if (aTargetSize) {
|
||||
@ -152,7 +150,8 @@ DecoderFactory::CreateDecoder(DecoderType aType,
|
||||
DecoderFactory::CreateAnimationDecoder(DecoderType aType,
|
||||
RasterImage* aImage,
|
||||
SourceBuffer* aSourceBuffer,
|
||||
uint32_t aFlags,
|
||||
DecoderFlags aDecoderFlags,
|
||||
SurfaceFlags aSurfaceFlags,
|
||||
const IntSize& aResolution)
|
||||
{
|
||||
if (aType == DecoderType::UNKNOWN) {
|
||||
@ -169,9 +168,9 @@ DecoderFactory::CreateAnimationDecoder(DecoderType aType,
|
||||
// Initialize the decoder.
|
||||
decoder->SetMetadataDecode(false);
|
||||
decoder->SetIterator(aSourceBuffer->Iterator());
|
||||
decoder->SetFlags(aFlags);
|
||||
decoder->SetDecoderFlags(aDecoderFlags | DecoderFlags::IS_REDECODE);
|
||||
decoder->SetSurfaceFlags(aSurfaceFlags);
|
||||
decoder->SetResolution(aResolution);
|
||||
decoder->SetSendPartialInvalidations(false);
|
||||
|
||||
decoder->Init();
|
||||
if (NS_FAILED(decoder->GetDecoderError())) {
|
||||
@ -213,7 +212,7 @@ DecoderFactory::CreateMetadataDecoder(DecoderType aType,
|
||||
/* static */ already_AddRefed<Decoder>
|
||||
DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
|
||||
SourceBuffer* aSourceBuffer,
|
||||
uint32_t aFlags)
|
||||
SurfaceFlags aSurfaceFlags)
|
||||
{
|
||||
if (aType == DecoderType::UNKNOWN) {
|
||||
return nullptr;
|
||||
@ -226,15 +225,20 @@ DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
|
||||
// Initialize the decoder.
|
||||
decoder->SetMetadataDecode(false);
|
||||
decoder->SetIterator(aSourceBuffer->Iterator());
|
||||
decoder->SetFlags(aFlags);
|
||||
decoder->SetImageIsTransient(true);
|
||||
|
||||
// Anonymous decoders are always transient; we don't want to optimize surfaces
|
||||
// or do any other expensive work that might be wasted.
|
||||
DecoderFlags decoderFlags = DecoderFlags::IMAGE_IS_TRANSIENT;
|
||||
|
||||
// Without an image, the decoder can't store anything in the SurfaceCache, so
|
||||
// callers will only be able to retrieve the most recent frame via
|
||||
// Decoder::GetCurrentFrame(). That means that anonymous decoders should
|
||||
// always be first-frame-only decoders, because nobody ever wants the *last*
|
||||
// frame.
|
||||
decoder->SetIsFirstFrameDecode();
|
||||
decoderFlags |= DecoderFlags::FIRST_FRAME_ONLY;
|
||||
|
||||
decoder->SetDecoderFlags(decoderFlags);
|
||||
decoder->SetSurfaceFlags(aSurfaceFlags);
|
||||
|
||||
decoder->Init();
|
||||
if (NS_FAILED(decoder->GetDecoderError())) {
|
||||
@ -259,7 +263,7 @@ DecoderFactory::CreateAnonymousMetadataDecoder(DecoderType aType,
|
||||
// Initialize the decoder.
|
||||
decoder->SetMetadataDecode(true);
|
||||
decoder->SetIterator(aSourceBuffer->Iterator());
|
||||
decoder->SetIsFirstFrameDecode();
|
||||
decoder->SetDecoderFlags(DecoderFlags::FIRST_FRAME_ONLY);
|
||||
|
||||
decoder->Init();
|
||||
if (NS_FAILED(decoder->GetDecoderError())) {
|
||||
|
@ -7,9 +7,12 @@
|
||||
#ifndef mozilla_image_DecoderFactory_h
|
||||
#define mozilla_image_DecoderFactory_h
|
||||
|
||||
#include "DecoderFlags.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "SurfaceFlags.h"
|
||||
|
||||
class nsACString;
|
||||
|
||||
@ -20,6 +23,10 @@ class Decoder;
|
||||
class RasterImage;
|
||||
class SourceBuffer;
|
||||
|
||||
/**
|
||||
* The type of decoder; this is usually determined from a MIME type using
|
||||
* DecoderFactory::GetDecoderType().
|
||||
*/
|
||||
enum class DecoderType
|
||||
{
|
||||
PNG,
|
||||
@ -42,10 +49,6 @@ public:
|
||||
* (If the image *is* animated, only the first frame will be decoded.) The
|
||||
* decoder will send notifications to @aImage.
|
||||
*
|
||||
* XXX(seth): @aIsRedecode and @aImageIsTransient should really be part of
|
||||
* @aFlags. This requires changes to the way that decoder flags work, though.
|
||||
* See bug 1185800.
|
||||
*
|
||||
* @param aType Which type of decoder to create - JPEG, PNG, etc.
|
||||
* @param aImage The image will own the decoder and which should receive
|
||||
* notifications as decoding progresses.
|
||||
@ -55,25 +58,23 @@ public:
|
||||
* be scaled to during decoding. It's an error to specify
|
||||
* a target size for a decoder type which doesn't support
|
||||
* downscale-during-decode.
|
||||
* @param aFlags Flags specifying what type of output the decoder should
|
||||
* produce; see GetDecodeFlags() in RasterImage.h.
|
||||
* @param aDecoderFlags Flags specifying the behavior of this decoder.
|
||||
* @param aSurfaceFlags Flags specifying the type of output this decoder
|
||||
* should produce.
|
||||
* @param aSampleSize The sample size requested using #-moz-samplesize (or 0
|
||||
* if none).
|
||||
* @param aResolution The resolution requested using #-moz-resolution (or an
|
||||
* empty rect if none).
|
||||
* @param aIsRedecode Specify 'true' if this image has been decoded before.
|
||||
* @param aImageIsTransient Specify 'true' if this image is transient.
|
||||
*/
|
||||
static already_AddRefed<Decoder>
|
||||
CreateDecoder(DecoderType aType,
|
||||
RasterImage* aImage,
|
||||
SourceBuffer* aSourceBuffer,
|
||||
const Maybe<gfx::IntSize>& aTargetSize,
|
||||
uint32_t aFlags,
|
||||
DecoderFlags aDecoderFlags,
|
||||
SurfaceFlags aSurfaceFlags,
|
||||
int aSampleSize,
|
||||
const gfx::IntSize& aResolution,
|
||||
bool aIsRedecode,
|
||||
bool aImageIsTransient);
|
||||
const gfx::IntSize& aResolution);
|
||||
|
||||
/**
|
||||
* Creates and initializes a decoder for animated images of type @aType.
|
||||
@ -84,8 +85,9 @@ public:
|
||||
* notifications as decoding progresses.
|
||||
* @param aSourceBuffer The SourceBuffer which the decoder will read its data
|
||||
* from.
|
||||
* @param aFlags Flags specifying what type of output the decoder should
|
||||
* produce; see GetDecodeFlags() in RasterImage.h.
|
||||
* @param aDecoderFlags Flags specifying the behavior of this decoder.
|
||||
* @param aSurfaceFlags Flags specifying the type of output this decoder
|
||||
* should produce.
|
||||
* @param aResolution The resolution requested using #-moz-resolution (or an
|
||||
* empty rect if none).
|
||||
*/
|
||||
@ -93,7 +95,8 @@ public:
|
||||
CreateAnimationDecoder(DecoderType aType,
|
||||
RasterImage* aImage,
|
||||
SourceBuffer* aSourceBuffer,
|
||||
uint32_t aFlags,
|
||||
DecoderFlags aDecoderFlags,
|
||||
SurfaceFlags aSurfaceFlags,
|
||||
const gfx::IntSize& aResolution);
|
||||
|
||||
/**
|
||||
@ -126,13 +129,13 @@ public:
|
||||
* @param aType Which type of decoder to create - JPEG, PNG, etc.
|
||||
* @param aSourceBuffer The SourceBuffer which the decoder will read its data
|
||||
* from.
|
||||
* @param aFlags Flags specifying what type of output the decoder should
|
||||
* produce; see GetDecodeFlags() in RasterImage.h.
|
||||
* @param aSurfaceFlags Flags specifying the type of output this decoder
|
||||
* should produce.
|
||||
*/
|
||||
static already_AddRefed<Decoder>
|
||||
CreateAnonymousDecoder(DecoderType aType,
|
||||
SourceBuffer* aSourceBuffer,
|
||||
uint32_t aFlags);
|
||||
SurfaceFlags aSurfaceFlags);
|
||||
|
||||
/**
|
||||
* Creates and initializes an anonymous metadata decoder (one which isn't
|
||||
@ -143,8 +146,6 @@ public:
|
||||
* @param aType Which type of decoder to create - JPEG, PNG, etc.
|
||||
* @param aSourceBuffer The SourceBuffer which the decoder will read its data
|
||||
* from.
|
||||
* @param aFlags Flags specifying what type of output the decoder should
|
||||
* produce; see GetDecodeFlags() in RasterImage.h.
|
||||
*/
|
||||
static already_AddRefed<Decoder>
|
||||
CreateAnonymousMetadataDecoder(DecoderType aType,
|
||||
|
42
image/DecoderFlags.h
Normal file
42
image/DecoderFlags.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_image_DecoderFlags_h
|
||||
#define mozilla_image_DecoderFlags_h
|
||||
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
/**
|
||||
* Flags that influence decoder behavior. Note that these flags *don't*
|
||||
* influence the logical content of the surfaces that the decoder generates, so
|
||||
* they're not in a factor in SurfaceCache lookups and the like. These flags
|
||||
* instead either influence which surfaces are generated at all or the tune the
|
||||
* decoder's behavior for a particular scenario.
|
||||
*/
|
||||
enum class DecoderFlags : uint8_t
|
||||
{
|
||||
FIRST_FRAME_ONLY = 1 << 0,
|
||||
IS_REDECODE = 1 << 1,
|
||||
IMAGE_IS_TRANSIENT = 1 << 2,
|
||||
ASYNC_NOTIFY = 1 << 3
|
||||
};
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DecoderFlags)
|
||||
|
||||
/**
|
||||
* @return the default set of decode flags.
|
||||
*/
|
||||
inline DecoderFlags
|
||||
DefaultDecoderFlags()
|
||||
{
|
||||
return DecoderFlags();
|
||||
}
|
||||
|
||||
} // namespace image
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_image_DecoderFlags_h
|
@ -281,7 +281,7 @@ FrameAnimator::GetCompositedFrame(uint32_t aFrameNum)
|
||||
LookupResult result =
|
||||
SurfaceCache::Lookup(ImageKey(mImage),
|
||||
RasterSurfaceKey(mSize,
|
||||
0, // Default decode flags.
|
||||
DefaultSurfaceFlags(),
|
||||
aFrameNum));
|
||||
MOZ_ASSERT(!result || !result.DrawableRef()->GetIsPaletted(),
|
||||
"About to return a paletted frame");
|
||||
@ -332,7 +332,7 @@ DoCollectSizeOfCompositingSurfaces(const RawAccessFrameRef& aSurface,
|
||||
{
|
||||
// Concoct a SurfaceKey for this surface.
|
||||
SurfaceKey key = RasterSurfaceKey(aSurface->GetImageSize(),
|
||||
imgIContainer::DECODE_FLAGS_DEFAULT,
|
||||
DefaultSurfaceFlags(),
|
||||
/* aFrameNum = */ 0);
|
||||
|
||||
// Create a counter for this surface.
|
||||
@ -374,7 +374,7 @@ FrameAnimator::GetRawFrame(uint32_t aFrameNum) const
|
||||
LookupResult result =
|
||||
SurfaceCache::Lookup(ImageKey(mImage),
|
||||
RasterSurfaceKey(mSize,
|
||||
0, // Default decode flags.
|
||||
DefaultSurfaceFlags(),
|
||||
aFrameNum));
|
||||
return result ? result.DrawableRef()->RawAccessRef()
|
||||
: RawAccessFrameRef();
|
||||
|
@ -116,7 +116,9 @@ ImageOps::DecodeToSurface(nsIInputStream* aInputStream,
|
||||
DecoderType decoderType =
|
||||
DecoderFactory::GetDecoderType(PromiseFlatCString(aMimeType).get());
|
||||
nsRefPtr<Decoder> decoder =
|
||||
DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, aFlags);
|
||||
DecoderFactory::CreateAnonymousDecoder(decoderType,
|
||||
sourceBuffer,
|
||||
ToSurfaceFlags(aFlags));
|
||||
if (!decoder) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -118,7 +118,9 @@ public:
|
||||
// Insert the new surface into the cache immediately. We need to do this so
|
||||
// that we won't start multiple scaling jobs for the same size.
|
||||
SurfaceCache::Insert(mDstRef.get(), ImageKey(mImage.get()),
|
||||
RasterSurfaceKey(mDstSize, mImageFlags, 0),
|
||||
RasterSurfaceKey(mDstSize,
|
||||
ToSurfaceFlags(mImageFlags),
|
||||
/* aFrameNum = */ 0),
|
||||
Lifetime::Transient);
|
||||
|
||||
return true;
|
||||
@ -168,7 +170,8 @@ public:
|
||||
// Remove the frame from the cache since we know we don't need it.
|
||||
SurfaceCache::RemoveSurface(ImageKey(mImage.get()),
|
||||
RasterSurfaceKey(mDstSize,
|
||||
mImageFlags, 0));
|
||||
ToSurfaceFlags(mImageFlags),
|
||||
/* aFrameNum = */ 0));
|
||||
|
||||
// Release everything we're holding, too.
|
||||
mSrcRef.reset();
|
||||
@ -425,17 +428,18 @@ RasterImage::LookupFrameInternal(uint32_t aFrameNum,
|
||||
}
|
||||
|
||||
if (mAnim && aFrameNum > 0) {
|
||||
MOZ_ASSERT(DecodeFlags(aFlags) == DECODE_FLAGS_DEFAULT,
|
||||
"Can't composite frames with non-default decode flags");
|
||||
MOZ_ASSERT(ToSurfaceFlags(aFlags) == DefaultSurfaceFlags(),
|
||||
"Can't composite frames with non-default surface flags");
|
||||
return mAnim->GetCompositedFrame(aFrameNum);
|
||||
}
|
||||
|
||||
Maybe<uint32_t> alternateFlags;
|
||||
Maybe<SurfaceFlags> alternateFlags;
|
||||
if (IsOpaque()) {
|
||||
// If we're opaque, we can always substitute a frame that was decoded with a
|
||||
// different decode flag for premultiplied alpha, because that can only
|
||||
// matter for frames with transparency.
|
||||
alternateFlags = Some(aFlags ^ FLAG_DECODE_NO_PREMULTIPLY_ALPHA);
|
||||
alternateFlags.emplace(ToSurfaceFlags(aFlags) ^
|
||||
SurfaceFlags::NO_PREMULTIPLY_ALPHA);
|
||||
}
|
||||
|
||||
// We don't want any substitution for sync decodes (except the premultiplied
|
||||
@ -443,7 +447,7 @@ RasterImage::LookupFrameInternal(uint32_t aFrameNum,
|
||||
if (aFlags & FLAG_SYNC_DECODE) {
|
||||
return SurfaceCache::Lookup(ImageKey(this),
|
||||
RasterSurfaceKey(aSize,
|
||||
DecodeFlags(aFlags),
|
||||
ToSurfaceFlags(aFlags),
|
||||
aFrameNum),
|
||||
alternateFlags);
|
||||
}
|
||||
@ -451,7 +455,7 @@ RasterImage::LookupFrameInternal(uint32_t aFrameNum,
|
||||
// We'll return the best match we can find to the requested frame.
|
||||
return SurfaceCache::LookupBestMatch(ImageKey(this),
|
||||
RasterSurfaceKey(aSize,
|
||||
DecodeFlags(aFlags),
|
||||
ToSurfaceFlags(aFlags),
|
||||
aFrameNum),
|
||||
alternateFlags);
|
||||
}
|
||||
@ -1408,18 +1412,31 @@ RasterImage::Decode(const IntSize& aSize, uint32_t aFlags)
|
||||
|
||||
Maybe<IntSize> targetSize = mSize != aSize ? Some(aSize) : Nothing();
|
||||
|
||||
// Determine which flags we need to decode this image with.
|
||||
DecoderFlags decoderFlags = DefaultDecoderFlags();
|
||||
if (aFlags & FLAG_ASYNC_NOTIFY) {
|
||||
decoderFlags |= DecoderFlags::ASYNC_NOTIFY;
|
||||
}
|
||||
if (mTransient) {
|
||||
decoderFlags |= DecoderFlags::IMAGE_IS_TRANSIENT;
|
||||
}
|
||||
if (mHasBeenDecoded) {
|
||||
decoderFlags |= DecoderFlags::IS_REDECODE;
|
||||
}
|
||||
|
||||
// Create a decoder.
|
||||
nsRefPtr<Decoder> decoder;
|
||||
if (mAnim) {
|
||||
decoder = DecoderFactory::CreateAnimationDecoder(mDecoderType, this,
|
||||
mSourceBuffer, aFlags,
|
||||
mSourceBuffer, decoderFlags,
|
||||
ToSurfaceFlags(aFlags),
|
||||
mRequestedResolution);
|
||||
} else {
|
||||
decoder = DecoderFactory::CreateDecoder(mDecoderType, this, mSourceBuffer,
|
||||
targetSize, aFlags,
|
||||
targetSize, decoderFlags,
|
||||
ToSurfaceFlags(aFlags),
|
||||
mRequestedSampleSize,
|
||||
mRequestedResolution,
|
||||
mHasBeenDecoded, mTransient);
|
||||
mRequestedResolution);
|
||||
}
|
||||
|
||||
// Make sure DecoderFactory was able to create a decoder successfully.
|
||||
@ -1432,7 +1449,7 @@ RasterImage::Decode(const IntSize& aSize, uint32_t aFlags)
|
||||
InsertOutcome outcome =
|
||||
SurfaceCache::InsertPlaceholder(ImageKey(this),
|
||||
RasterSurfaceKey(aSize,
|
||||
decoder->GetDecodeFlags(),
|
||||
decoder->GetSurfaceFlags(),
|
||||
/* aFrameNum = */ 0));
|
||||
if (outcome != InsertOutcome::SUCCESS) {
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -1641,7 +1658,7 @@ RasterImage::RequestScale(imgFrame* aFrame,
|
||||
}
|
||||
|
||||
nsRefPtr<ScaleRunner> runner =
|
||||
new ScaleRunner(this, DecodeFlags(aFlags), aSize, Move(frameRef));
|
||||
new ScaleRunner(this, aFlags, aSize, Move(frameRef));
|
||||
if (runner->Init()) {
|
||||
if (!sScaleWorkerThread) {
|
||||
NS_NewNamedThread("Image Scaler", getter_AddRefs(sScaleWorkerThread));
|
||||
@ -1666,8 +1683,8 @@ RasterImage::DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef,
|
||||
LookupResult result =
|
||||
SurfaceCache::Lookup(ImageKey(this),
|
||||
RasterSurfaceKey(aSize,
|
||||
DecodeFlags(aFlags),
|
||||
0));
|
||||
ToSurfaceFlags(aFlags),
|
||||
/* aFrameNum = */ 0));
|
||||
if (!result) {
|
||||
// We either didn't have a matching scaled frame or the OS threw it away.
|
||||
// Request a new one so we'll be ready next time. For now, we'll fall back
|
||||
@ -1746,7 +1763,7 @@ RasterImage::Draw(gfxContext* aContext,
|
||||
// Illegal -- you can't draw with non-default decode flags.
|
||||
// (Disabling colorspace conversion might make sense to allow, but
|
||||
// we don't currently.)
|
||||
if (DecodeFlags(aFlags) != DECODE_FLAGS_DEFAULT) {
|
||||
if (ToSurfaceFlags(aFlags) != DefaultSurfaceFlags()) {
|
||||
return DrawResult::BAD_ARGS;
|
||||
}
|
||||
|
||||
@ -1937,14 +1954,15 @@ RasterImage::GetFramesNotified(uint32_t* aFramesNotified)
|
||||
void
|
||||
RasterImage::NotifyProgress(Progress aProgress,
|
||||
const IntRect& aInvalidRect /* = IntRect() */,
|
||||
uint32_t aFlags /* = DECODE_FLAGS_DEFAULT */)
|
||||
SurfaceFlags aSurfaceFlags
|
||||
/* = DefaultSurfaceFlags() */)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Ensure that we stay alive long enough to finish notifying.
|
||||
nsRefPtr<RasterImage> image(this);
|
||||
|
||||
bool wasDefaultFlags = aFlags == DECODE_FLAGS_DEFAULT;
|
||||
bool wasDefaultFlags = aSurfaceFlags == DefaultSurfaceFlags();
|
||||
|
||||
if (!aInvalidRect.IsEmpty() && wasDefaultFlags) {
|
||||
// Update our image container since we're invalidating.
|
||||
@ -1989,7 +2007,7 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder)
|
||||
// Send out any final notifications.
|
||||
NotifyProgress(aDecoder->TakeProgress(),
|
||||
aDecoder->TakeInvalidRect(),
|
||||
aDecoder->GetDecodeFlags());
|
||||
aDecoder->GetSurfaceFlags());
|
||||
|
||||
bool wasMetadata = aDecoder->IsMetadataDecode();
|
||||
bool done = aDecoder->GetDecodeDone();
|
||||
@ -2094,8 +2112,8 @@ RasterImage::OptimalImageSizeForDest(const gfxSize& aDest, uint32_t aWhichFrame,
|
||||
LookupResult result =
|
||||
SurfaceCache::Lookup(ImageKey(this),
|
||||
RasterSurfaceKey(destSize,
|
||||
DecodeFlags(aFlags),
|
||||
0));
|
||||
ToSurfaceFlags(aFlags),
|
||||
/* aFrameNum = */ 0));
|
||||
|
||||
if (result && result.DrawableRef()->IsImageComplete()) {
|
||||
return destSize; // We have an existing HQ scale for this size.
|
||||
|
@ -135,17 +135,6 @@ class FrameAnimator;
|
||||
class ImageMetadata;
|
||||
class SourceBuffer;
|
||||
|
||||
/**
|
||||
* Given a set of imgIContainer FLAG_* flags, returns those flags that can
|
||||
* affect the output of decoders.
|
||||
*/
|
||||
inline MOZ_CONSTEXPR uint32_t
|
||||
DecodeFlags(uint32_t aFlags)
|
||||
{
|
||||
return aFlags & (imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA |
|
||||
imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION);
|
||||
}
|
||||
|
||||
class RasterImage final : public ImageResource
|
||||
, public nsIProperties
|
||||
, public SupportsWeakPtr<RasterImage>
|
||||
@ -196,13 +185,13 @@ public:
|
||||
*
|
||||
* @param aProgress The progress notifications to send.
|
||||
* @param aInvalidRect An invalidation rect to send.
|
||||
* @param aFlags The decode flags used by the decoder that generated
|
||||
* these notifications, or DECODE_FLAGS_DEFAULT if the
|
||||
* @param aFlags The surface flags used by the decoder that generated
|
||||
* these notifications, or DefaultSurfaceFlags() if the
|
||||
* notifications don't come from a decoder.
|
||||
*/
|
||||
void NotifyProgress(Progress aProgress,
|
||||
const nsIntRect& aInvalidRect = nsIntRect(),
|
||||
uint32_t aFlags = DECODE_FLAGS_DEFAULT);
|
||||
SurfaceFlags aSurfaceFlags = DefaultSurfaceFlags());
|
||||
|
||||
/**
|
||||
* Records telemetry and does final teardown of the provided decoder.
|
||||
|
@ -283,7 +283,7 @@ public:
|
||||
|
||||
Pair<already_AddRefed<CachedSurface>, MatchType>
|
||||
LookupBestMatch(const SurfaceKey& aSurfaceKey,
|
||||
const Maybe<uint32_t>& aAlternateFlags)
|
||||
const Maybe<SurfaceFlags>& aAlternateFlags)
|
||||
{
|
||||
// Try for an exact match first.
|
||||
nsRefPtr<CachedSurface> exactMatch;
|
||||
@ -335,13 +335,13 @@ private:
|
||||
struct MatchContext
|
||||
{
|
||||
MatchContext(const SurfaceKey& aIdealKey,
|
||||
const Maybe<uint32_t>& aAlternateFlags)
|
||||
const Maybe<SurfaceFlags>& aAlternateFlags)
|
||||
: mIdealKey(aIdealKey)
|
||||
, mAlternateFlags(aAlternateFlags)
|
||||
{ }
|
||||
|
||||
const SurfaceKey& mIdealKey;
|
||||
const Maybe<uint32_t> mAlternateFlags;
|
||||
const Maybe<SurfaceFlags> mAlternateFlags;
|
||||
nsRefPtr<CachedSurface> mBestMatch;
|
||||
};
|
||||
|
||||
@ -644,7 +644,7 @@ public:
|
||||
|
||||
LookupResult LookupBestMatch(const ImageKey aImageKey,
|
||||
const SurfaceKey& aSurfaceKey,
|
||||
const Maybe<uint32_t>& aAlternateFlags)
|
||||
const Maybe<SurfaceFlags>& aAlternateFlags)
|
||||
{
|
||||
nsRefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
|
||||
if (!cache) {
|
||||
@ -1060,7 +1060,8 @@ SurfaceCache::Shutdown()
|
||||
/* static */ LookupResult
|
||||
SurfaceCache::Lookup(const ImageKey aImageKey,
|
||||
const SurfaceKey& aSurfaceKey,
|
||||
const Maybe<uint32_t>& aAlternateFlags /* = Nothing() */)
|
||||
const Maybe<SurfaceFlags>& aAlternateFlags
|
||||
/* = Nothing() */)
|
||||
{
|
||||
if (!sInstance) {
|
||||
return LookupResult(MatchType::NOT_FOUND);
|
||||
@ -1080,7 +1081,7 @@ SurfaceCache::Lookup(const ImageKey aImageKey,
|
||||
/* static */ LookupResult
|
||||
SurfaceCache::LookupBestMatch(const ImageKey aImageKey,
|
||||
const SurfaceKey& aSurfaceKey,
|
||||
const Maybe<uint32_t>& aAlternateFlags
|
||||
const Maybe<SurfaceFlags>& aAlternateFlags
|
||||
/* = Nothing() */)
|
||||
{
|
||||
if (!sInstance) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
#include "mozilla/gfx/Point.h" // for mozilla::gfx::IntSize
|
||||
#include "mozilla/gfx/2D.h" // for SourceSurface
|
||||
#include "SurfaceFlags.h"
|
||||
#include "SVGImageContext.h" // for SVGImageContext
|
||||
|
||||
namespace mozilla {
|
||||
@ -59,16 +60,16 @@ public:
|
||||
{
|
||||
uint32_t hash = HashGeneric(mSize.width, mSize.height);
|
||||
hash = AddToHash(hash, mSVGContext.map(HashSIC).valueOr(0));
|
||||
hash = AddToHash(hash, mAnimationTime, mFlags);
|
||||
hash = AddToHash(hash, mAnimationTime, uint32_t(mFlags));
|
||||
return hash;
|
||||
}
|
||||
|
||||
IntSize Size() const { return mSize; }
|
||||
Maybe<SVGImageContext> SVGContext() const { return mSVGContext; }
|
||||
float AnimationTime() const { return mAnimationTime; }
|
||||
uint32_t Flags() const { return mFlags; }
|
||||
SurfaceFlags Flags() const { return mFlags; }
|
||||
|
||||
SurfaceKey WithNewFlags(uint32_t aFlags) const
|
||||
SurfaceKey WithNewFlags(SurfaceFlags aFlags) const
|
||||
{
|
||||
return SurfaceKey(mSize, mSVGContext, mAnimationTime, aFlags);
|
||||
}
|
||||
@ -77,7 +78,7 @@ private:
|
||||
SurfaceKey(const IntSize& aSize,
|
||||
const Maybe<SVGImageContext>& aSVGContext,
|
||||
const float aAnimationTime,
|
||||
const uint32_t aFlags)
|
||||
const SurfaceFlags aFlags)
|
||||
: mSize(aSize)
|
||||
, mSVGContext(aSVGContext)
|
||||
, mAnimationTime(aAnimationTime)
|
||||
@ -88,7 +89,9 @@ private:
|
||||
return aSIC.Hash();
|
||||
}
|
||||
|
||||
friend SurfaceKey RasterSurfaceKey(const IntSize&, uint32_t, uint32_t);
|
||||
friend SurfaceKey RasterSurfaceKey(const IntSize&,
|
||||
SurfaceFlags,
|
||||
uint32_t);
|
||||
friend SurfaceKey VectorSurfaceKey(const IntSize&,
|
||||
const Maybe<SVGImageContext>&,
|
||||
float);
|
||||
@ -96,12 +99,12 @@ private:
|
||||
IntSize mSize;
|
||||
Maybe<SVGImageContext> mSVGContext;
|
||||
float mAnimationTime;
|
||||
uint32_t mFlags;
|
||||
SurfaceFlags mFlags;
|
||||
};
|
||||
|
||||
inline SurfaceKey
|
||||
RasterSurfaceKey(const gfx::IntSize& aSize,
|
||||
uint32_t aFlags,
|
||||
SurfaceFlags aFlags,
|
||||
uint32_t aFrameNum)
|
||||
{
|
||||
return SurfaceKey(aSize, Nothing(), float(aFrameNum), aFlags);
|
||||
@ -115,7 +118,7 @@ VectorSurfaceKey(const gfx::IntSize& aSize,
|
||||
// We don't care about aFlags for VectorImage because none of the flags we
|
||||
// have right now influence VectorImage's rendering. If we add a new flag that
|
||||
// *does* affect how a VectorImage renders, we'll have to change this.
|
||||
return SurfaceKey(aSize, aSVGContext, aAnimationTime, 0);
|
||||
return SurfaceKey(aSize, aSVGContext, aAnimationTime, DefaultSurfaceFlags());
|
||||
}
|
||||
|
||||
enum class Lifetime : uint8_t {
|
||||
@ -196,7 +199,8 @@ struct SurfaceCache
|
||||
*/
|
||||
static LookupResult Lookup(const ImageKey aImageKey,
|
||||
const SurfaceKey& aSurfaceKey,
|
||||
const Maybe<uint32_t>& aAlternateFlags = Nothing());
|
||||
const Maybe<SurfaceFlags>& aAlternateFlags
|
||||
= Nothing());
|
||||
|
||||
/**
|
||||
* Looks up the best matching surface in the cache and returns a drawable
|
||||
@ -224,7 +228,7 @@ struct SurfaceCache
|
||||
*/
|
||||
static LookupResult LookupBestMatch(const ImageKey aImageKey,
|
||||
const SurfaceKey& aSurfaceKey,
|
||||
const Maybe<uint32_t>& aAlternateFlags
|
||||
const Maybe<SurfaceFlags>& aAlternateFlags
|
||||
= Nothing());
|
||||
|
||||
/**
|
||||
|
56
image/SurfaceFlags.h
Normal file
56
image/SurfaceFlags.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_image_SurfaceFlags_h
|
||||
#define mozilla_image_SurfaceFlags_h
|
||||
|
||||
#include "imgIContainer.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
/**
|
||||
* Flags that change the output a decoder generates. Because different
|
||||
* combinations of these flags result in logically different surfaces, these
|
||||
* flags must be taken into account in SurfaceCache lookups.
|
||||
*/
|
||||
enum class SurfaceFlags : uint8_t
|
||||
{
|
||||
NO_PREMULTIPLY_ALPHA = 1 << 0,
|
||||
NO_COLORSPACE_CONVERSION = 1 << 1
|
||||
};
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(SurfaceFlags)
|
||||
|
||||
/**
|
||||
* @return the default set of surface flags.
|
||||
*/
|
||||
inline SurfaceFlags
|
||||
DefaultSurfaceFlags()
|
||||
{
|
||||
return SurfaceFlags();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a set of imgIContainer FLAG_* flags, returns a set of SurfaceFlags with
|
||||
* the corresponding flags set.
|
||||
*/
|
||||
inline SurfaceFlags
|
||||
ToSurfaceFlags(uint32_t aFlags)
|
||||
{
|
||||
SurfaceFlags flags = DefaultSurfaceFlags();
|
||||
if (aFlags & imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA) {
|
||||
flags |= SurfaceFlags::NO_PREMULTIPLY_ALPHA;
|
||||
}
|
||||
if (aFlags & imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION) {
|
||||
flags |= SurfaceFlags::NO_COLORSPACE_CONVERSION;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
} // namespace image
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_image_SurfaceFlags_h
|
@ -360,10 +360,8 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
if (mIsPNG) {
|
||||
mContainedDecoder = new nsPNGDecoder(mImage);
|
||||
mContainedDecoder->SetMetadataDecode(IsMetadataDecode());
|
||||
mContainedDecoder->SetSendPartialInvalidations(mSendPartialInvalidations);
|
||||
if (mFirstFrameDecode) {
|
||||
mContainedDecoder->SetIsFirstFrameDecode();
|
||||
}
|
||||
mContainedDecoder->SetDecoderFlags(GetDecoderFlags());
|
||||
mContainedDecoder->SetSurfaceFlags(GetSurfaceFlags());
|
||||
mContainedDecoder->Init();
|
||||
if (!WriteToContainedDecoder(mSignature, PNGSIGNATURESIZE)) {
|
||||
return;
|
||||
@ -440,10 +438,8 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
mContainedDecoder = bmpDecoder;
|
||||
bmpDecoder->SetUseAlphaData(true);
|
||||
mContainedDecoder->SetMetadataDecode(IsMetadataDecode());
|
||||
mContainedDecoder->SetSendPartialInvalidations(mSendPartialInvalidations);
|
||||
if (mFirstFrameDecode) {
|
||||
mContainedDecoder->SetIsFirstFrameDecode();
|
||||
}
|
||||
mContainedDecoder->SetDecoderFlags(GetDecoderFlags());
|
||||
mContainedDecoder->SetSurfaceFlags(GetSurfaceFlags());
|
||||
mContainedDecoder->Init();
|
||||
|
||||
// The ICO format when containing a BMP does not include the 14 byte
|
||||
|
@ -154,7 +154,7 @@ void
|
||||
nsJPEGDecoder::InitInternal()
|
||||
{
|
||||
mCMSMode = gfxPlatform::GetCMSMode();
|
||||
if (GetDecodeFlags() & imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION) {
|
||||
if (GetSurfaceFlags() & SurfaceFlags::NO_COLORSPACE_CONVERSION) {
|
||||
mCMSMode = eCMSMode_Off;
|
||||
}
|
||||
|
||||
|
@ -233,11 +233,11 @@ void
|
||||
nsPNGDecoder::InitInternal()
|
||||
{
|
||||
mCMSMode = gfxPlatform::GetCMSMode();
|
||||
if (GetDecodeFlags() & imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION) {
|
||||
if (GetSurfaceFlags() & SurfaceFlags::NO_COLORSPACE_CONVERSION) {
|
||||
mCMSMode = eCMSMode_Off;
|
||||
}
|
||||
mDisablePremultipliedAlpha =
|
||||
GetDecodeFlags() & imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
|
||||
bool(GetSurfaceFlags() & SurfaceFlags::NO_PREMULTIPLY_ALPHA);
|
||||
|
||||
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||
static png_byte color_chunks[]=
|
||||
|
@ -276,9 +276,10 @@ private:
|
||||
surfacePathPrefix.Append("@");
|
||||
surfacePathPrefix.AppendFloat(counter.Key().AnimationTime());
|
||||
|
||||
if (counter.Key().Flags() != imgIContainer::DECODE_FLAGS_DEFAULT) {
|
||||
if (counter.Key().Flags() != DefaultSurfaceFlags()) {
|
||||
surfacePathPrefix.Append(", flags:");
|
||||
surfacePathPrefix.AppendInt(counter.Key().Flags(), /* aRadix = */ 16);
|
||||
surfacePathPrefix.AppendInt(uint32_t(counter.Key().Flags()),
|
||||
/* aRadix = */ 16);
|
||||
}
|
||||
} else if (counter.Type() == SurfaceMemoryCounterType::COMPOSITING) {
|
||||
surfacePathPrefix.Append(", compositing frame");
|
||||
|
@ -46,6 +46,7 @@ EXPORTS += [
|
||||
'IProgressObserver.h',
|
||||
'Orientation.h',
|
||||
'SurfaceCache.h',
|
||||
'SurfaceFlags.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -111,7 +111,7 @@ CheckMetadata(const ImageTestCase& aTestCase,
|
||||
// Create a full decoder, so we can compare the result.
|
||||
decoder =
|
||||
DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer,
|
||||
imgIContainer::DECODE_FLAGS_DEFAULT);
|
||||
DefaultSurfaceFlags());
|
||||
ASSERT_TRUE(decoder != nullptr);
|
||||
|
||||
if (aBMPAlpha == BMPAlpha::ENABLED) {
|
||||
@ -241,14 +241,14 @@ TEST(ImageMetadata, NoFrameDelayGIFFullDecode)
|
||||
LookupResult firstFrameLookupResult =
|
||||
SurfaceCache::Lookup(ImageKey(image.get()),
|
||||
RasterSurfaceKey(imageSize,
|
||||
imgIContainer::DECODE_FLAGS_DEFAULT,
|
||||
DefaultSurfaceFlags(),
|
||||
/* aFrameNum = */ 0));
|
||||
EXPECT_EQ(MatchType::EXACT, firstFrameLookupResult.Type());
|
||||
|
||||
LookupResult secondFrameLookupResult =
|
||||
SurfaceCache::Lookup(ImageKey(image.get()),
|
||||
RasterSurfaceKey(imageSize,
|
||||
imgIContainer::DECODE_FLAGS_DEFAULT,
|
||||
DefaultSurfaceFlags(),
|
||||
/* aFrameNum = */ 1));
|
||||
EXPECT_EQ(MatchType::EXACT, secondFrameLookupResult.Type());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user