Bug 1337111 - Part 3. Land groundwork for new blended animation gtests. r=tnikkel

This commit is contained in:
Andrew Osmond 2018-09-17 15:06:29 -04:00
parent 5024f42bc6
commit 5fbd07b388
8 changed files with 80 additions and 23 deletions

View File

@ -453,6 +453,7 @@ public:
protected:
friend class AutoRecordDecoderTelemetry;
friend class DecoderTestHelper;
friend class nsICODecoder;
friend class PalettedSurfaceSink;
friend class SurfaceSink;

View File

@ -332,6 +332,7 @@ DecoderFactory::CreateDecoderForICOResource(DecoderType aType,
DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
NotNull<SourceBuffer*> aSourceBuffer,
const Maybe<IntSize>& aOutputSize,
DecoderFlags aDecoderFlags,
SurfaceFlags aSurfaceFlags)
{
if (aType == DecoderType::UNKNOWN) {
@ -350,14 +351,7 @@ DecoderFactory::CreateAnonymousDecoder(DecoderType aType,
// 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.
decoderFlags |= DecoderFlags::FIRST_FRAME_ONLY;
decoder->SetDecoderFlags(decoderFlags);
decoder->SetDecoderFlags(aDecoderFlags | decoderFlags);
decoder->SetSurfaceFlags(aSurfaceFlags);
// Set an output size for downscale-during-decode if requested.

View File

@ -177,6 +177,7 @@ public:
* smaller than the intrinsic size, the decoder will
* downscale the image. If Nothing(), the output size will
* be the intrinsic size.
* @param aDecoderFlags Flags specifying the behavior of this decoder.
* @param aSurfaceFlags Flags specifying the type of output this decoder
* should produce.
*/
@ -184,6 +185,7 @@ public:
CreateAnonymousDecoder(DecoderType aType,
NotNull<SourceBuffer*> aSourceBuffer,
const Maybe<gfx::IntSize>& aOutputSize,
DecoderFlags aDecoderFlags,
SurfaceFlags aSurfaceFlags);
/**

View File

@ -225,7 +225,9 @@ ImageOps::DecodeToSurface(ImageBuffer* aBuffer,
RefPtr<Decoder> decoder =
DecoderFactory::CreateAnonymousDecoder(decoderType,
WrapNotNull(sourceBuffer),
aSize, ToSurfaceFlags(aFlags));
aSize,
DecoderFlags::FIRST_FRAME_ONLY,
ToSurfaceFlags(aFlags));
if (!decoder) {
return nullptr;
}

View File

@ -195,20 +195,21 @@ RectIsSolidColor(SourceSurface* aSurface,
uint8_t* data = mapping.GetData();
ASSERT_TRUE_OR_RETURN(data != nullptr, false);
BGRAColor pmColor = aColor.Premultiply();
int32_t rowLength = mapping.GetStride();
for (int32_t row = rect.Y(); row < rect.YMost(); ++row) {
for (int32_t col = rect.X(); col < rect.XMost(); ++col) {
int32_t i = row * rowLength + col * 4;
if (aFuzz != 0) {
ASSERT_LE_OR_RETURN(abs(aColor.mBlue - data[i + 0]), aFuzz, false);
ASSERT_LE_OR_RETURN(abs(aColor.mGreen - data[i + 1]), aFuzz, false);
ASSERT_LE_OR_RETURN(abs(aColor.mRed - data[i + 2]), aFuzz, false);
ASSERT_LE_OR_RETURN(abs(aColor.mAlpha - data[i + 3]), aFuzz, false);
ASSERT_LE_OR_RETURN(abs(pmColor.mBlue - data[i + 0]), aFuzz, false);
ASSERT_LE_OR_RETURN(abs(pmColor.mGreen - data[i + 1]), aFuzz, false);
ASSERT_LE_OR_RETURN(abs(pmColor.mRed - data[i + 2]), aFuzz, false);
ASSERT_LE_OR_RETURN(abs(pmColor.mAlpha - data[i + 3]), aFuzz, false);
} else {
ASSERT_EQ_OR_RETURN(aColor.mBlue, data[i + 0], false);
ASSERT_EQ_OR_RETURN(aColor.mGreen, data[i + 1], false);
ASSERT_EQ_OR_RETURN(aColor.mRed, data[i + 2], false);
ASSERT_EQ_OR_RETURN(aColor.mAlpha, data[i + 3], false);
ASSERT_EQ_OR_RETURN(pmColor.mBlue, data[i + 0], false);
ASSERT_EQ_OR_RETURN(pmColor.mGreen, data[i + 1], false);
ASSERT_EQ_OR_RETURN(pmColor.mRed, data[i + 2], false);
ASSERT_EQ_OR_RETURN(pmColor.mAlpha, data[i + 3], false);
}
}
}
@ -300,6 +301,7 @@ CreateTrivialDecoder()
auto sourceBuffer = MakeNotNull<RefPtr<SourceBuffer>>();
RefPtr<Decoder> decoder =
DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, Nothing(),
DefaultDecoderFlags(),
DefaultSurfaceFlags());
return decoder.forget();
}

View File

@ -10,6 +10,7 @@
#include "gtest/gtest.h"
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/gfx/2D.h"
@ -75,11 +76,12 @@ struct BGRAColor
{
BGRAColor() : BGRAColor(0, 0, 0, 0) { }
BGRAColor(uint8_t aBlue, uint8_t aGreen, uint8_t aRed, uint8_t aAlpha)
BGRAColor(uint8_t aBlue, uint8_t aGreen, uint8_t aRed, uint8_t aAlpha, bool aPremultiplied = false)
: mBlue(aBlue)
, mGreen(aGreen)
, mRed(aRed)
, mAlpha(aAlpha)
, mPremultiplied(aPremultiplied)
{ }
static BGRAColor Green() { return BGRAColor(0x00, 0xFF, 0x00, 0xFF); }
@ -87,12 +89,30 @@ struct BGRAColor
static BGRAColor Blue() { return BGRAColor(0xFF, 0x00, 0x00, 0xFF); }
static BGRAColor Transparent() { return BGRAColor(0x00, 0x00, 0x00, 0x00); }
uint32_t AsPixel() const { return gfxPackedPixel(mAlpha, mRed, mGreen, mBlue); }
BGRAColor Premultiply() const
{
if (!mPremultiplied) {
return BGRAColor(gfxPreMultiply(mBlue, mAlpha),
gfxPreMultiply(mGreen, mAlpha),
gfxPreMultiply(mRed, mAlpha),
mAlpha,
true);
}
return *this;
}
uint32_t AsPixel() const {
if (!mPremultiplied) {
return gfxPackedPixel(mAlpha, mRed, mGreen, mBlue);
}
return gfxPackedPixelNoPreMultiply(mAlpha, mRed, mGreen, mBlue);
}
uint8_t mBlue;
uint8_t mGreen;
uint8_t mRed;
uint8_t mAlpha;
bool mPremultiplied;
};
@ -241,7 +261,7 @@ already_AddRefed<Decoder> CreateTrivialDecoder();
* @param aConfigs The configuration for the pipeline.
*/
template <typename Func, typename... Configs>
void WithFilterPipeline(Decoder* aDecoder, Func aFunc, const Configs&... aConfigs)
void WithFilterPipeline(Decoder* aDecoder, Func aFunc, bool aFinish, const Configs&... aConfigs)
{
auto pipe = MakeUnique<typename detail::FilterPipeline<Configs...>::Type>();
nsresult rv = pipe->Configure(aConfigs...);
@ -249,12 +269,20 @@ void WithFilterPipeline(Decoder* aDecoder, Func aFunc, const Configs&... aConfig
aFunc(aDecoder, pipe.get());
RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
if (currentFrame) {
currentFrame->Finish();
if (aFinish) {
RawAccessFrameRef currentFrame = aDecoder->GetCurrentFrameRef();
if (currentFrame) {
currentFrame->Finish();
}
}
}
template <typename Func, typename... Configs>
void WithFilterPipeline(Decoder* aDecoder, Func aFunc, const Configs&... aConfigs)
{
WithFilterPipeline(aDecoder, aFunc, true, aConfigs...);
}
/**
* Creates a pipeline of SurfaceFilters from a list of Config structs and
* asserts that configuring it fails. Cleanup of any allocated surfaces is
@ -369,6 +397,31 @@ void CheckPalettedWritePixels(Decoder* aDecoder,
const Maybe<gfx::IntRect>& aOutputWriteRect = Nothing(),
uint8_t aFuzz = 0);
///////////////////////////////////////////////////////////////////////////////
// Decoder Helpers
///////////////////////////////////////////////////////////////////////////////
// Friend class of Decoder to access internals for tests.
class MOZ_STACK_CLASS DecoderTestHelper final
{
public:
explicit DecoderTestHelper(Decoder* aDecoder)
: mDecoder(aDecoder)
{ }
void PostIsAnimated(FrameTimeout aTimeout)
{
mDecoder->PostIsAnimated(aTimeout);
}
void PostFrameStop(Opacity aOpacity)
{
mDecoder->PostFrameStop(aOpacity);
}
private:
Decoder* mDecoder;
};
///////////////////////////////////////////////////////////////////////////////
// Test Data

View File

@ -115,6 +115,7 @@ void WithSingleChunkDecode(const ImageTestCase& aTestCase,
DecoderFactory::GetDecoderType(aTestCase.mMimeType);
RefPtr<Decoder> decoder =
DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, aOutputSize,
DecoderFlags::FIRST_FRAME_ONLY,
DefaultSurfaceFlags());
ASSERT_TRUE(decoder != nullptr);
RefPtr<IDecodingTask> task = new AnonymousDecodingTask(WrapNotNull(decoder));
@ -152,6 +153,7 @@ CheckDecoderMultiChunk(const ImageTestCase& aTestCase)
DecoderFactory::GetDecoderType(aTestCase.mMimeType);
RefPtr<Decoder> decoder =
DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, Nothing(),
DecoderFlags::FIRST_FRAME_ONLY,
DefaultSurfaceFlags());
ASSERT_TRUE(decoder != nullptr);
RefPtr<IDecodingTask> task = new AnonymousDecodingTask(WrapNotNull(decoder));

View File

@ -108,6 +108,7 @@ CheckMetadata(const ImageTestCase& aTestCase,
// Create a full decoder, so we can compare the result.
decoder =
DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, Nothing(),
DecoderFlags::FIRST_FRAME_ONLY,
DefaultSurfaceFlags());
ASSERT_TRUE(decoder != nullptr);
task = new AnonymousDecodingTask(WrapNotNull(decoder));