author | Seth Fowler <mark.seth.fowler@gmail.com> |
Fri, 27 May 2016 12:59:19 -0700 | |
changeset 299410 | 3b02a890b94e4b1879f0bd8e2361444e17de5dc5 |
parent 299409 | 2e2085781ab223642bb266ff729a7569fdaf1858 |
child 299411 | 3a61f536f0e6b992ddc587a2d4620e58da3a2fe6 |
push id | 30297 |
push user | cbook@mozilla.com |
push date | Mon, 30 May 2016 13:29:51 +0000 |
treeherder | mozilla-central@3435dd7ad71f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | njn |
bugs | 1207830 |
milestone | 49.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/image/DecoderFactory.cpp +++ b/image/DecoderFactory.cpp @@ -199,16 +199,17 @@ DecoderFactory::CreateMetadataDecoder(De } return decoder.forget(); } /* static */ already_AddRefed<Decoder> DecoderFactory::CreateAnonymousDecoder(DecoderType aType, SourceBuffer* aSourceBuffer, + const Maybe<IntSize>& aTargetSize, SurfaceFlags aSurfaceFlags) { if (aType == DecoderType::UNKNOWN) { return nullptr; } RefPtr<Decoder> decoder = GetDecoder(aType, /* aImage = */ nullptr, /* aIsRedecode = */ false); @@ -227,16 +228,22 @@ DecoderFactory::CreateAnonymousDecoder(D // 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->SetSurfaceFlags(aSurfaceFlags); + // Set a target size for downscale-during-decode if applicable. + if (aTargetSize) { + DebugOnly<nsresult> rv = decoder->SetTargetSize(*aTargetSize); + MOZ_ASSERT(NS_SUCCEEDED(rv), "Bad downscale-during-decode target size?"); + } + decoder->Init(); if (NS_FAILED(decoder->GetDecoderError())) { return nullptr; } return decoder.forget(); }
--- a/image/DecoderFactory.h +++ b/image/DecoderFactory.h @@ -115,22 +115,27 @@ public: /** * Creates and initializes an anonymous decoder (one which isn't associated * with an Image object). Only the first frame of the image will be decoded. * * @param aType Which type of decoder to create - JPEG, PNG, etc. * @param aSourceBuffer The SourceBuffer which the decoder will read its data * from. + * @param aTargetSize If not Nothing(), the target size which the image should + * 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 aSurfaceFlags Flags specifying the type of output this decoder * should produce. */ static already_AddRefed<Decoder> CreateAnonymousDecoder(DecoderType aType, SourceBuffer* aSourceBuffer, + const Maybe<gfx::IntSize>& aTargetSize, SurfaceFlags aSurfaceFlags); /** * Creates and initializes an anonymous metadata decoder (one which isn't * associated with an Image object). This decoder will only decode the image's * header, extracting metadata like the size of the image. No actual image * data will be decoded and no surfaces will be allocated. *
--- a/image/ImageOps.cpp +++ b/image/ImageOps.cpp @@ -115,16 +115,17 @@ ImageOps::DecodeToSurface(nsIInputStream sourceBuffer->Complete(NS_OK); // Create a decoder. DecoderType decoderType = DecoderFactory::GetDecoderType(PromiseFlatCString(aMimeType).get()); RefPtr<Decoder> decoder = DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, + Nothing(), ToSurfaceFlags(aFlags)); if (!decoder) { return nullptr; } // Run the decoder synchronously. decoder->Decode(); if (!decoder->GetDecodeDone() || decoder->HasError()) {
--- a/image/test/gtest/Common.cpp +++ b/image/test/gtest/Common.cpp @@ -156,17 +156,17 @@ RectIsSolidColor(SourceSurface* aSurface already_AddRefed<Decoder> CreateTrivialDecoder() { gfxPrefs::GetSingleton(); DecoderType decoderType = DecoderFactory::GetDecoderType("image/gif"); RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(); RefPtr<Decoder> decoder = - DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, + DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, Nothing(), DefaultSurfaceFlags()); return decoder.forget(); } void AssertCorrectPipelineFinalState(SurfaceFilter* aFilter, const gfx::IntRect& aInputSpaceRect, const gfx::IntRect& aOutputSpaceRect) {
--- a/image/test/gtest/TestDecoders.cpp +++ b/image/test/gtest/TestDecoders.cpp @@ -99,17 +99,17 @@ CheckDecoderSingleChunk(const ImageTestC rv = sourceBuffer->AppendFromInputStream(inputStream, length); ASSERT_TRUE(NS_SUCCEEDED(rv)); sourceBuffer->Complete(NS_OK); // Create a decoder. DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType); RefPtr<Decoder> decoder = - DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, + DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, Nothing(), DefaultSurfaceFlags()); ASSERT_TRUE(decoder != nullptr); // Run the full decoder synchronously. decoder->Decode(); CheckDecoderResults(aTestCase, decoder); } @@ -136,17 +136,17 @@ CheckDecoderMultiChunk(const ImageTestCa ASSERT_TRUE(NS_SUCCEEDED(rv)); // Create a SourceBuffer and a decoder. RefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(); sourceBuffer->ExpectLength(length); DecoderType decoderType = DecoderFactory::GetDecoderType(aTestCase.mMimeType); RefPtr<Decoder> decoder = - DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, + DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, Nothing(), DefaultSurfaceFlags()); ASSERT_TRUE(decoder != nullptr); // Decode synchronously, using a |NoResume| IResumable so the Decoder doesn't // attempt to schedule itself on a nonexistent DecodePool when we write more // data into the SourceBuffer. RefPtr<NoResume> noResume = new NoResume(); for (uint64_t read = 0; read < length ; ++read) {
--- a/image/test/gtest/TestMetadata.cpp +++ b/image/test/gtest/TestMetadata.cpp @@ -105,17 +105,17 @@ CheckMetadata(const ImageTestCase& aTest : bool(aTestCase.mFlags & TEST_CASE_IS_TRANSPARENT); EXPECT_EQ(expectTransparency, bool(metadataProgress & FLAG_HAS_TRANSPARENCY)); EXPECT_EQ(bool(aTestCase.mFlags & TEST_CASE_IS_ANIMATED), bool(metadataProgress & FLAG_IS_ANIMATED)); // Create a full decoder, so we can compare the result. decoder = - DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, + DecoderFactory::CreateAnonymousDecoder(decoderType, sourceBuffer, Nothing(), DefaultSurfaceFlags()); ASSERT_TRUE(decoder != nullptr); if (aBMPWithinICO == BMPWithinICO::YES) { static_cast<nsBMPDecoder*>(decoder.get())->SetIsWithinICO(); } // Run the full decoder synchronously.