зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1337111 - Part 3. Land groundwork for new blended animation gtests. r=tnikkel
This commit is contained in:
Родитель
5024f42bc6
Коммит
5fbd07b388
|
@ -453,6 +453,7 @@ public:
|
|||
|
||||
protected:
|
||||
friend class AutoRecordDecoderTelemetry;
|
||||
friend class DecoderTestHelper;
|
||||
friend class nsICODecoder;
|
||||
friend class PalettedSurfaceSink;
|
||||
friend class SurfaceSink;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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));
|
||||
|
|
Загрузка…
Ссылка в новой задаче